package org.reborn.engine.input.jinput

import org.reborn.engine.input._

import net.java.games.input.{Controller,ControllerEnvironment,Mouse=>JIMouse,Keyboard=>JIKeyboard,ControllerListener,ControllerEvent};

/**
 * Object for getting input controllers (mice, keyboards, joysticks, etc...)
 */
object JInput {
  val controllerEvents = new ControllerEventHandler()
  private lazy val jiEnvironment = configureEnvironment
  
  private def configureEnvironment():ControllerEnvironment = {
	val environment = ControllerEnvironment.getDefaultEnvironment
	environment.addControllerListener(controllerEvents)
	environment
  }
  
  /**
   * Gets a list of all attached input devices
   */
  def getControllers():List[Controller] = {
	jiEnvironment.getControllers.toList
  }
  
  /**
   * Gets the first Mouse from list of input devices, or None if no mice are attached
   */
  def GetDefaultMouse():Option[Mouse] = {
	val cont = getControllers.find(_.getType == Controller.Type.MOUSE)
	
	//safe to cast as a Mouse
	cont.map{(exists)=>
	  val mouse = exists.asInstanceOf[JIMouse]
	  new JInputMouse(mouse)
	}
  }
  
  /**
   * Gets the first Keyboard from list of input devices, or None if no keyboards are attached
   */
  def GetDefaultKeyboard():Option[Keyboard] = {
	val cont = getControllers.find(_.getType == Controller.Type.KEYBOARD)
	
	//safe to cast as a Keyboard
	cont.map{(exists)=>
	  val keyboard = exists.asInstanceOf[JIKeyboard]
	  new JInputKeyboard(keyboard)
	}
  }
}

class ControllerEventHandler extends ControllerListener{
  type EventHandler = (ControllerEvent) => Unit
  
  private var connectHandlerList:List[EventHandler] = Nil
  private var disconnectHandlerList:List[EventHandler] = Nil
  
  def connectEventHandler_+=(handler:EventHandler) = {connectHandlerList = connectHandlerList ::: List(handler)}
  def connectEventHandler_-=(handler:EventHandler) = {connectHandlerList = connectHandlerList.filterNot(_ == handler)}
  def removeAllConnectEventHandlers() = {connectHandlerList = Nil}
  
  def disconnectEventHandler_+=(handler:EventHandler) = {disconnectHandlerList = disconnectHandlerList ::: List(handler)}
  def disconnectEventHandler_-=(handler:EventHandler) = {disconnectHandlerList = disconnectHandlerList.filterNot(_ == handler)}
  def removeAllDisconnectEventHandlers() = {disconnectHandlerList = Nil}
  
  def controllerAdded(event:ControllerEvent):Unit = {
	//Invoke all the registered event handlers for when a controller is connected
	for(handler <- connectHandlerList){
	  handler(event)
	}
  }
  
  def controllerRemoved(event:ControllerEvent):Unit = {
	//Invoke all the registered event handlers for when a controller is disconnected
	for(handler <- disconnectHandlerList){
	  handler(event)
	}
  }
}